/**
 * 事件总线 - 插件间通信的核心
 * 提供发布/订阅模式的事件系统
 */

type EventHandler = (data?: unknown) => void

export class EventBus {
  private events: Map<string, Set<EventHandler>>

  constructor() {
    this.events = new Map()
  }

  /**
   * 订阅事件
   * @param event 事件名称
   * @param handler 事件处理函数
   * @returns 取消订阅函数
   */
  on(event: string, handler: EventHandler): () => void {
    if (!this.events.has(event)) {
      this.events.set(event, new Set())
    }

    this.events.get(event)!.add(handler)

    // 返回取消订阅函数
    return () => this.off(event, handler)
  }

  /**
   * 取消订阅事件
   * @param event 事件名称
   * @param handler 事件处理函数
   */
  off(event: string, handler: EventHandler): void {
    const handlers = this.events.get(event)
    if (handlers) {
      handlers.delete(handler)
      if (handlers.size === 0) {
        this.events.delete(event)
      }
    }
  }

  /**
   * 发布事件
   * @param event 事件名称
   * @param data 事件数据
   */
  emit(event: string, data?: unknown): void {
    const handlers = this.events.get(event)
    if (handlers) {
      handlers.forEach(handler => {
        try {
          handler(data)
        } catch (error) {
          console.error(`Error in event handler for "${event}":`, error)
        }
      })
    }
  }

  /**
   * 只订阅一次事件
   * @param event 事件名称
   * @param handler 事件处理函数
   */
  once(event: string, handler: EventHandler): void {
    const wrappedHandler: EventHandler = data => {
      handler(data)
      this.off(event, wrappedHandler)
    }
    this.on(event, wrappedHandler)
  }

  /**
   * 清除所有事件监听
   */
  clear(): void {
    this.events.clear()
  }

  /**
   * 清除指定事件的所有监听
   * @param event 事件名称
   */
  clearEvent(event: string): void {
    this.events.delete(event)
  }

  /**
   * 获取事件的监听器数量
   * @param event 事件名称
   */
  listenerCount(event: string): number {
    return this.events.get(event)?.size || 0
  }

  /**
   * 获取所有事件名称
   */
  eventNames(): string[] {
    return Array.from(this.events.keys())
  }
}
